#include "includes.h"

void fragment_test(heap876* heap){
	heap->free_all(0);
	char** c = new char*[heap->get_occupancy()];
	for (int i = 0; i < 100; i++){
		for(UINT j=0; j < heap->get_occupancy(); j++)
			if( !(c[j] = (char*) heap->alloc(1))) std::cout << "FAIL" << std::endl;
		for(UINT j=0; j < heap->get_occupancy(); j++)
			heap->free((void*)c[j]);
		std::cout << "ITERATION " << i << " OK" << std::endl;
	}
	delete [] c;
	if(heap->alloc(heap->get_occupancy())) std::cout << "FULL MEMORY USE TEST: OK" << std::endl;
	heap->free_all(0);
}

void print_info(heap876* heap){
	std::cout << "author: " << heap->get_name() << "\t memory total: " << heap->get_occupancy() << std::endl;
}

void limits_test(heap876* heap){
	heap->free_all(0);
	heap->alloc(100);
	try{
		free((void*)-1234);
		free((void*)'d');
		int x;
		free(&x);
	}
	catch(...)
	{
		std::cout<<"Test finished successfully" << std::endl;
		return;
	}

	std::cout<<"Wrong memory has been released!" << std::endl; 
	heap->free_all(0);
}

DWORD WINAPI TestingThread( LPVOID lpParam ) //Thread for testing
{
	int* pn;
	std::cout<<"Thread started..."<<std::endl;
	heap876* hp = (heap876*)lpParam;

	std::cout << "trying to alloc 5 bytes..." << std::endl;
	pn = (int*)hp->alloc(5);
	hp->free(pn);
    return 0;
}

void multihreading_test(heap876* hp){
	const int N = 10;
	try{

		HANDLE hThread[N];
		for (int i = 0; i < N; i++){
			hThread[i] = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)(TestingThread), hp, 0, 0);
            WaitForMultipleObjects(N, hThread, TRUE, INFINITE);
		}
	} 
	catch (std::exception e) {
		std::cout << e.what();
    }
}


int main(){
	heap_petrov* hp = new heap_petrov(100, heap876::alloc_simple);
	//fragment_test(hp);
	multihreading_test(hp);
	//limits_test(hp);
	print_info(hp);


}	/*
	heap_petrov hp(100, heap876::alloc_simple);
	hp.prt();
	
	char* c1 = (char*) hp.alloc(4);
	char* c2 = (char*) hp.alloc(3);
	char* c3 = (char*) hp.alloc(2);
	char* c4 = (char*) hp.alloc(7);
	char* c5 = (char*) hp.alloc(8);
	char* c6 = (char*) hp.alloc(4);
	char* c7 = (char*) hp.alloc(8);
	hp.prt();
	
	hp.free(c2);
	hp.free(c4);
	hp.free(c6);
	hp.prt();

	c2 = (char*) hp.alloc(1);
	c4 = (char*) hp.alloc(4);
	hp.prt();
	std::cout << (void*)c2 << " " << (void*)c4 << std::endl;

	fragment_test(&hp);

	char c;
	std::cin.getline(&c, 1);
	return 0;


}
*/